home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1994 November / macformat-018.iso / Utility Spectacular / Developer / NFind / Sources / NewFindTool.c next >
Encoding:
C/C++ Source or Header  |  1991-02-18  |  26.1 KB  |  691 lines  |  [TEXT/MPS ]

  1. /* NewFindTool.c
  2.  *
  3.  * MPW tool to provide an enhanced front end to the standard MPW shell find command
  4.  */
  5.  
  6. #include <Strings.h>
  7. #include <Signal.h>
  8. #include <StdLib.h>
  9. #include <Scrap.h>
  10. #include <ToolUtils.h>
  11. #include <Lists.h>
  12. #include <Types.h>
  13. #include <Dialogs.h>
  14. #include <TextEdit.h>
  15. #include <Events.h>
  16. #include <OSEvents.h>
  17. #include <Fonts.h>
  18. #include <Quickdraw.h>
  19. #include <StdIo.h>
  20. #include <String.h>
  21.  
  22. pascal char InputFilter(DialogPtr pdlogFind,EventRecord *pevntFind,short *psHit);
  23. void RefreshDialog(DialogPtr pdlogFind);
  24. void QuoteString(char *pszOutString,char *pszInString);
  25. void FindDialog(void);
  26. void main(void);
  27.  
  28. #define FIND_BUTTON                    1
  29. #define CANCEL_BUTTON                2
  30. #define CASE_SENSITIVE_CHECK        3
  31. #define SEARCH_BACKWARD_CHECK        4
  32. #define LITERAL_RADIO                5
  33. #define ENTIRE_WORD_RADIO            6
  34. #define SELECTION_EXPRESSION_RADIO    7
  35. #define FIND_TEXT_EDIT                8
  36.  
  37. char chDialogExit;                    /* flag used to exit the dialog */
  38. char chDoubleClick;                    /* flag to say that a double click on a list happened */
  39. Point ptAction;                     /* current list selection point */
  40. ListHandle hlistFind;                /* handle for a list in the dialog */
  41. Rect rectFindList;                     /* rectangle for my list */
  42. short sFontNum;
  43.  
  44. pascal char InputFilter(DialogPtr pglogFind,EventRecord *pevntFind,short *psHit)
  45. /* dialog input filter */
  46.  
  47. {
  48. Rect rectTemp;
  49. char chRetVal,chTest;
  50. short sDialogType,sLen;
  51. Handle hdlogItem;
  52. int iKeyCode,iCharCode;
  53. Boolean fcmdDown;
  54. Cell cellTemp;
  55. Str255 strTemp;
  56.  
  57. chRetVal = false;                                                                    /* initialize */
  58. if (pevntFind->what == mouseDown)
  59.     {
  60.     /* there was a mouse down event */
  61.     ptAction = pevntFind->where;                                                     /* get click position */
  62.     GlobalToLocal(&ptAction);                                                        /* convert to local coordinates */
  63.     if (PtInRect(ptAction,&rectFindList) == true)
  64.         {
  65.         /* an event occured in the find text list */
  66.         chDoubleClick = LClick(ptAction,pevntFind->modifiers,hlistFind);
  67.         if (chDoubleClick == true)
  68.             {
  69.             cellTemp = LLastClick(hlistFind);                                        /* find where the click occured */
  70.             sLen = 255;                                                                /* maximum data length */
  71.             LGetCell((strTemp + 1),&sLen,cellTemp,hlistFind);                        /* get a copy of the clicked on text */
  72.             strTemp[0] = (unsigned char) sLen;                                        /* set the length byte */
  73.             GetDItem(pglogFind,FIND_TEXT_EDIT,&sDialogType,&hdlogItem,&rectTemp);    /* get the item handle */
  74.             SetIText(hdlogItem,strTemp);                                            /* set the new text string */
  75.             SelIText(pglogFind,FIND_TEXT_EDIT,sLen,sLen);                            /* set the new insertion point */
  76.             *psHit = FIND_TEXT_EDIT;                                                /* signal item affected */
  77.             chRetVal = true;                                                        /* signal processing complete */
  78.             }  /* if chDoubleClick */
  79.         }  /* if PtInRect() */
  80.     }  /* if pevntFind */
  81. else
  82.     {
  83.     if (pevntFind->what == keyDown)
  84.         {
  85.         /* there was a keypress event */
  86.         iKeyCode = pevntFind->message & keyCodeMask;                                /* get the key code */
  87.         iKeyCode = iKeyCode >> 8;                                                     /* shift to low order byte */
  88.         if ((iKeyCode == 0x24) || (iKeyCode == 0x4c))
  89.             {
  90.             /* Return or Enter were pressed - treat as exit request */
  91.             chRetVal = true;                                                        /* signal processing complete */
  92.             *psHit = ok;                                                            /* signal item affected */
  93.             }  /* if iKeyCode */
  94.         else
  95.             {
  96.             fcmdDown = ((pevntFind->modifiers & cmdKey) != 0);                        /* is the Command key down? */
  97.             if (fcmdDown)
  98.                 {
  99.                 *psHit = ((DialogPeek) pglogFind)->editField + 1;                     /* signal item effected (current TE field) */
  100.                 iCharCode = pevntFind->message & charCodeMask;                        /* get the character code */
  101.                 chTest = (char) iCharCode;                                            /* convert it to a character */
  102.                 switch (chTest)
  103.                     {
  104.                     case 'x' :
  105.                         {
  106.                         DlgCut(pglogFind);                                            /* perform cut to scrap */
  107.                         chRetVal = true;                                            /* signal processing complete */
  108.                         break;
  109.                         }  /* case 'x' */
  110.                     case 'c' :
  111.                         {
  112.                         DlgCopy(pglogFind);                                         /* perform copy to scrap */
  113.                         chRetVal = true;                                            /* signal processing complete */
  114.                         break;
  115.                         }  /* case 'c' */
  116.                     case 'v' :
  117.                         {
  118.                         DlgPaste(pglogFind);                                        /* perform paste from scrap */
  119.                         chRetVal = true;                                            /* signal processing complete */
  120.                         break;
  121.                         }  /* case 'v' */
  122.                     case '.' :
  123.                         {
  124.                         chRetVal = true;                                            /* signal processing complete */
  125.                         *psHit = cancel;                                            /* signal item affected */
  126.                         break;
  127.                         }  /* case '.' */
  128.                     }  /* switch chTest */
  129.                 }  /* if fcmdDown */
  130.             }  /* else if iKeyCode */
  131.         }  /* if pevntFind */
  132.     else
  133.         {
  134.         if (pevntFind->what == updateEvt)
  135.             {
  136.             if (IsDialogEvent(pevntFind))
  137.                 {
  138.                 RefreshDialog(pglogFind);                                            /* update the non-controls */
  139.                 }  /* if IsDialogEvent() */
  140.             }  /* if pevntFind */
  141.         }  /* else if pevntFind */
  142.     }  /* else if pevntFind */
  143. return chRetVal;                                                                    /* signal if processing is complete */
  144. }  /* InputFilter() */
  145.  
  146. void RefreshDialog(DialogPtr pdlogFind)
  147. /* update non-controls in the dialog */ 
  148.  
  149. {
  150. Rect rectTemp;
  151. short sDialogType,sTemp;
  152. Handle hdlogItem;
  153. ControlHandle hctrlItem;
  154.  
  155. GetDItem(pdlogFind,FIND_BUTTON,&sDialogType,&hdlogItem,&rectTemp);                    /* get the item handle */
  156. PenSize(3,3);                                                                        /* change pen to draw thick default outline */
  157. InsetRect(&rectTemp,-4,-4);                                                         /* draw outside the button by 1 pixel */
  158. FrameRoundRect(&rectTemp,16,16);                                                    /* draw the outline */
  159. PenSize(1,1);                                                                        /* restore the pen size to the default value */
  160.  
  161. /* Draw the upper divide line */
  162. PenPat(qd.gray);                                                                    /* set this to a gray line */
  163. MoveTo(15,204);                                                                     /* move to starting position */
  164. LineTo(350,204);                                                                    /* draw to ending position */
  165.  
  166. /* Draw the lower divide line */
  167. MoveTo(15,280);                                                                     /* move to starting position */
  168. LineTo(350,280);                                                                    /* draw to ending position */
  169. PenPat(qd.black);                                                                    /* revert to default pen pattern */
  170.  
  171. /* Draw the find prompt text */
  172. TextFont(systemFont);
  173. TextSize(12);
  174. GetDItem(pdlogFind,SELECTION_EXPRESSION_RADIO,&sDialogType,&hdlogItem,&rectTemp);    /* get the item handle */
  175. hctrlItem = (ControlHandle) hdlogItem;                                                /* change dialog handle to control handle */
  176. sTemp = GetCtlValue(hctrlItem);                                                        /*    get the current Checkbox value */
  177. SetRect(&rectTemp,47,153,317,169);
  178. EraseRect(&rectTemp);
  179. MoveTo(47,166);
  180. if (sTemp)
  181.     {
  182.     DrawString("\pFind what selection expression?");
  183.     }  /* if sTemp */
  184. else
  185.     {
  186.     DrawString("\pFind what string?");
  187.     }  /* else if sTemp */
  188. TextFont(sFontNum);
  189. TextSize(9);
  190.     
  191. LUpdate(pdlogFind->visRgn,hlistFind);                                                /* update this list */
  192. rectTemp = rectFindList;                                                            /* start with full size */
  193. InsetRect(&rectTemp,-1,-1);                                                         /* set for framing */
  194. FrameRect(&rectTemp);                                                                /* frame it */
  195. }  /* RefreshDialog() */
  196.  
  197. void AddListString(Str255 *strAdd,ListHandle hlstString)
  198. /* add strings to an existing list */
  199.  
  200. {
  201. short sRow;
  202. Point ptSize;
  203.  
  204. if (hlstString != nil) 
  205.     {
  206.     ptSize.h = 0;                                            /* point to the correct column */
  207.     sRow = LAddRow(1,32000,hlstString);                        /* add another row at the end of the list */
  208.     ptSize.v = sRow;                                        /* point to the row just added */
  209.     LSetCell((*strAdd + 1),*strAdd[0],ptSize,hlstString);     /* place string in row just created */
  210.     LDraw(ptSize,hlstString);                                /* draw the new string */
  211.     }  /* if hlstString */
  212. }  /* AddListString() */
  213.  
  214. void QuoteString(char *pszOutString,char *pszInString)
  215. /* quote ' characters in the input string */
  216.  
  217. {
  218. char *pchEnd,*pchLast,*pchStart;
  219.  
  220. *pszOutString = '\0';                                                            /* initialize to empty */
  221. pchStart = pszInString;                                                            /* initialize */
  222. pchEnd = pszInString;                                                            /* initialize */
  223. pchLast = pchStart + strlen(pszInString);
  224. while (pchEnd != NULL)
  225.     {
  226.     pchEnd = strchr(pchStart,(int) '\'');                                        /* find the next occurance of the character ', if any */
  227.     if ((pchEnd != NULL) && (pchStart <= pchLast))
  228.         {
  229.         /* a ' character was found */
  230.         (void) strncat(pszOutString,pchStart,(size_t) (pchEnd - pchStart));        /* concatenate the input string up to but not including the ' character */
  231.         (void) strcat(pszOutString,"'∂''");                                        /* quote the ' character as ∂' */
  232.         pchStart = pchEnd + 1;                                                    /* update the string start position */
  233.         }  /* if pchEnd */
  234.     else
  235.         {
  236.         /* no more ' characters to be found */
  237.         (void) strcat(pszOutString,pchStart);                                    /* concatenate the remaining input string */
  238.         }  /* else if pchEnd */
  239.     }  /* while pchEnd */
  240. }  /* QuoteString() */
  241.  
  242. void FindDialog(void)
  243. /* Find dialog box routine */
  244.  
  245. {
  246. DialogPtr pdlogFind;
  247. Rect rectData,rectTemp;
  248. short sDialogType,sIndex,sHit,sTemp,sSearchType;
  249. Boolean fBeep,fGoOn,fMatch,fReverse,fSearchBackward;
  250. Handle hdlogItem;
  251. ControlHandle hctrlItem,hctrlTemp;
  252. Str255 strTemp;
  253. Point ptCSize;
  254. TEHandle hteString;
  255. DialogPeek pkdlogFind;
  256. char *pszEnv;
  257. char achTemp[256],achQuote[256];
  258. size_t usLen;
  259. FILE *pfilSetup,*pfilFindCommand;
  260. FontInfo fntiPrompt;
  261. KeyMap kmapExit;
  262.  
  263. pdlogFind = GetNewDialog(2,nil,(WindowPtr) -1);                                                                        /* bring in the dialog resource */
  264. pszEnv = getenv("font");
  265. (void) strcpy(achTemp,pszEnv);
  266. c2pstr(achTemp);
  267. GetFNum(achTemp,&sFontNum);
  268.  
  269. rectTemp.top = pdlogFind->portRect.top;                                                                                /* get window size, we will now center it */
  270. rectTemp.left = pdlogFind->portRect.left;                                                                            /* ditto */
  271. rectTemp.bottom = pdlogFind->portRect.bottom;                                                                        /* ditto */
  272. rectTemp.right = pdlogFind->portRect.right;                                                                            /* ditto */
  273. rectTemp.top = -pdlogFind->portBits.bounds.top;                                                                        /* fixed vertical position */
  274. rectTemp.left = ((qd.screenBits.bounds.right - qd.screenBits.bounds.left) - (rectTemp.right - rectTemp.left)) / 2;    /* center horizontally */
  275. MoveWindow(pdlogFind,rectTemp.left,rectTemp.top,true);                                                                /* move the window to the proper position */
  276. SetPort(pdlogFind);                                                                                                    /* prepare to add conditional text */
  277.  
  278. TextFont(sFontNum);
  279. TextSize(9);
  280. GetFontInfo(&fntiPrompt);
  281. pkdlogFind = (DialogPeek) pdlogFind;                                                                                /* get to the inner record */
  282. hteString = pkdlogFind->textH;                                                                                         /* get to the TE record */
  283. HLock((Handle) hteString);                                                                                            /* lock it for safety */
  284. (*hteString)->txFont = sFontNum;
  285. (*hteString)->txSize = 9;
  286. (*hteString)->fontAscent = fntiPrompt.ascent;
  287. (*hteString)->lineHeight = fntiPrompt.ascent + fntiPrompt.descent + fntiPrompt.leading;
  288. HUnlock((Handle) hteString);                                                                                         /* unLock the handle when done */
  289.  
  290. SetRect(&rectFindList,47,15,317,147);
  291. rectTemp = rectFindList;                                                                                            /* start with full size */
  292. rectTemp.right = rectTemp.right - 15;                                                                                /* make room for the scroll bar on the right */
  293. if (rectTemp.right <= (rectTemp.left + 15))
  294.     {
  295.     /* Safety check */
  296.     rectTemp.right = rectTemp.left + 15;
  297.     }  /* if rectTemp */
  298. InsetRect(&rectTemp,-1,-1);                                                                                         /* set for framing */
  299. FrameRect(&rectTemp);                                                                                                /* frame it */
  300. InsetRect(&rectTemp,1,1);                                                                                            /* restore */
  301. SetRect(&rectData,0,0,1,0);                                                                                            /* set up list */
  302. ptCSize.h = rectTemp.right - rectTemp.left;                                                                            /* width of the list */
  303. ptCSize.v = 0;                                                                                                        /* let List Manager determine the height */
  304. hlistFind = LNew(&rectTemp,&rectData,ptCSize,0,pdlogFind,true,false,false,true);                                    /* make the list */
  305. HLock((Handle) hlistFind);
  306. (*hlistFind)->selFlags = lOnlyOne + lNoNilHilite;                                                                    /* set the attributes */
  307. HUnlock((Handle) hlistFind);
  308. LDoDraw(true,hlistFind);                                                                                            /* draw the list */
  309.  
  310. pszEnv = getenv("findstrings");                                                                                        /* get a pointer to the FindStrings environment variable */
  311. if (pszEnv != NULL)
  312.     {
  313.     pfilSetup = fopen(pszEnv,"r");                                                                                    /* try to open the file for reading */
  314.     if (pfilSetup != NULL)
  315.         {
  316.         sIndex = 0;
  317.         while (!feof(pfilSetup))
  318.             {
  319.             if (fgets(achTemp,256,pfilSetup) != NULL)
  320.                 {
  321.                 usLen = strlen(achTemp);
  322.                 if (usLen > 0)
  323.                     {
  324.                     if (*(achTemp + usLen - 1) == (char) '\n')
  325.                         {
  326.                         usLen--;
  327.                         *(achTemp + usLen) = '\0';                                                                    /* remove the line feed character */
  328.                         }  /* if *achTemp */
  329.                     c2pstr(achTemp);
  330.                     AddListString((Str255 *)achTemp,hlistFind);
  331.                     sIndex++;
  332.                     }  /* if usLen */
  333.                 }  /* if fgets() */
  334.             }  /* while !feof() */
  335.         (void) fclose(pfilSetup);
  336.         if (sIndex > 0)
  337.             {
  338.             ptCSize.v = sIndex - 1;                                                                                    /* cell row of last item */
  339.             ptCSize.h = 0;                                                                                            /* set cell column */
  340.             LSetSelect(true,ptCSize,hlistFind);                                                                        /* select the cell */
  341.             LAutoScroll(hlistFind);                                                                                    /* scroll as necessary to display the selected item */
  342.             }  /* if sIndex */
  343.         }  /* if pfilSetup */
  344.     }  /* if pszEnv */
  345.  
  346. /* set up check boxes according to the enviroment variables */
  347. GetDItem(pdlogFind,CASE_SENSITIVE_CHECK,&sDialogType,&hdlogItem,&rectTemp);                                            /* get the item handle */
  348. hctrlTemp = (ControlHandle) hdlogItem;                                                                                /* change dialog handle to control handle */
  349. pszEnv = getenv("casesensitive");                                                                                    /* get a pointer to the CaseSensitive environment variable */
  350. if (atoi(pszEnv) == 0)
  351.     {
  352.     SetCtlValue(hctrlTemp,0);                                                                                        /* turn the check box off */
  353.     }  /* if atoi() */
  354. else
  355.     {
  356.     SetCtlValue(hctrlTemp,1);                                                                                        /* turn the check box on */
  357.     }  /* else if atoi() */
  358. GetDItem(pdlogFind,SEARCH_BACKWARD_CHECK,&sDialogType,&hdlogItem,&rectTemp);                                        /* get the item handle */
  359. hctrlTemp = (ControlHandle) hdlogItem;                                                                                /* change dialog handle to control handle */
  360. pszEnv = getenv("searchbackward");                                                                                    /* get a pointer to the SearchBackward environment variable */
  361. if (atoi(pszEnv) == 0)
  362.     {
  363.     SetCtlValue(hctrlTemp,0);                                                                                        /* turn the check box off */
  364.     }  /* if atoi() */
  365. else
  366.     {
  367.     SetCtlValue(hctrlTemp,1);                                                                                        /* turn the check box on */
  368.     }  /* else if atoi() */
  369.  
  370. /* set up radio buttons according to the enviroment variable */
  371. for (sIndex = LITERAL_RADIO; sIndex <= SELECTION_EXPRESSION_RADIO; sIndex++)
  372.     {
  373.     /* clear all radios */
  374.     GetDItem(pdlogFind,sIndex,&sDialogType,&hdlogItem,&rectTemp);                                                    /* get the Radio handle */
  375.     hctrlTemp = (ControlHandle) hdlogItem;                                                                            /* get the control handle */
  376.     SetCtlValue(hctrlTemp,0);                                                                                        /* turn the radio selection off */
  377.     }  /* for sIndex */
  378. pszEnv = getenv("searchtype");                                                                                        /* get a pointer to the SearchType environment variable */
  379. sIndex = LITERAL_RADIO + atoi(pszEnv);                                                                                /* get the default radio sIndex */
  380. GetDItem(pdlogFind,sIndex,&sDialogType,&hdlogItem,&rectTemp);                                                        /* get the item handle */
  381. hctrlItem = (ControlHandle) hdlogItem;                                                                                /* change dialog handle to control handle */
  382. SetCtlValue(hctrlItem,1);                                                                                            /* select the radio */
  383.  
  384. /* set up initial highlighting */
  385. if (sIndex == SELECTION_EXPRESSION_RADIO)
  386.     {
  387.     GetDItem(pdlogFind,SEARCH_BACKWARD_CHECK,&sDialogType,&hdlogItem,&rectTemp);                                    /* get the item handle */
  388.     hctrlTemp = (ControlHandle) hdlogItem;                                                                            /* change dialog handle to control handle */
  389.     HiliteControl(hctrlTemp,255);                                                                                    /* set to disabled */
  390.     }  /* if sIndex */
  391.  
  392. /* set up the default find string/selection expression according to the enviroment variables */
  393. GetDItem(pdlogFind,FIND_TEXT_EDIT,&sDialogType,&hdlogItem,&rectTemp);                                                /* get the item handle */
  394. pszEnv = getenv("lastfindstring");                                                                                    /* get a pointer to the LastFindString environment variable */
  395. if (pszEnv != NULL)
  396.     {
  397.     pfilSetup = fopen(pszEnv,"r");                                                                                    /* try to open the file for reading */
  398.     if (pfilSetup != NULL)
  399.         {
  400.         if (fgets(achTemp,256,pfilSetup) != NULL)
  401.             {
  402.             usLen = strlen(achTemp);
  403.             if (usLen > 0)
  404.                 {
  405.                 if (*(achTemp + usLen - 1) == (char) '\n')
  406.                     {
  407.                     usLen--;
  408.                     *(achTemp + usLen) = '\0';                                                                        /* remove the line feed character */
  409.                     }  /* if *achTemp */
  410.                 }  /* if usLen */
  411.             }  /* if fgets() */
  412.         (void) fclose(pfilSetup);
  413.         }  /* if pfilSetup */
  414.     c2pstr(achTemp);
  415.     SetIText(hdlogItem,achTemp);
  416.     SelIText(pdlogFind,FIND_TEXT_EDIT,0,(short) strlen(pszEnv));                                                    /* set the new insertion point */
  417.     }  /* if pszEnv */
  418. else
  419.     {
  420.     SetIText(hdlogItem,"\p");
  421.     SelIText(pdlogFind,FIND_TEXT_EDIT,0,0);                                                                            /* set the new insertion point */
  422.     }  /* else if pszEnv */
  423.  
  424. RefreshDialog(pdlogFind);                                                                                            /* draw the non-controls */
  425. ShowWindow(pdlogFind);                                                                                                /* open a dialog box */
  426. SelectWindow(pdlogFind);                                                                                             /* make it visible */
  427.  
  428. chDialogExit = false;                                                                                                 /* do not exit dialog handle loop yet */
  429. do
  430.     {
  431.     ModalDialog((ModalFilterProcPtr) InputFilter,&sHit);                                                             /* wait until an item is hit */
  432.     GetDItem(pdlogFind,sHit,&sDialogType,&hdlogItem,&rectTemp);                                                     /* get item information */
  433.     hctrlItem = (ControlHandle) hdlogItem;                                                                            /* get the control handle */
  434.     
  435.     if (sHit == FIND_BUTTON)
  436.         {
  437.         chDialogExit = true;                                                                                        /* exit the dialog when this selection is made */
  438.         }  /* if sHit */
  439.     
  440.     if (sHit == CANCEL_BUTTON)
  441.         {
  442.         chDialogExit = true;                                                                                        /* exit the dialog when this selection is made */
  443.         }  /* if sHit */
  444.     
  445.     if (sHit == CASE_SENSITIVE_CHECK)
  446.         {
  447.         sTemp = GetCtlValue(hctrlItem);                                                                                /*    get the current Checkbox value */
  448.         SetCtlValue(hctrlItem,((sTemp + 1) & 1));                                                                    /* toggle the value */
  449.         }  /* if sHit */
  450.     
  451.     if (sHit == SEARCH_BACKWARD_CHECK)
  452.         {
  453.         sTemp = GetCtlValue(hctrlItem);                                                                                /*    get the current Checkbox value */
  454.         SetCtlValue(hctrlItem,((sTemp + 1) & 1));                                                                    /* toggle the value */
  455.         }  /* if sHit */
  456.     
  457.     if ((sHit >= LITERAL_RADIO) && (sHit <= SELECTION_EXPRESSION_RADIO))
  458.         {
  459.         if (sHit == SELECTION_EXPRESSION_RADIO)
  460.             {
  461.             sTemp = GetCtlValue(hctrlItem);                                                                            /*    get the current Checkbox value */
  462.             if (!(sTemp & 1))
  463.                 {
  464.                 /* disable SEARCH_BACKWARD_CHECK */
  465.                 GetDItem(pdlogFind,SEARCH_BACKWARD_CHECK,&sDialogType,&hdlogItem,&rectTemp);                        /* get the item handle */
  466.                 hctrlTemp = (ControlHandle) hdlogItem;                                                                /* change dialog handle to control handle */
  467.                 HiliteControl(hctrlTemp,255);                                                                        /* set to disabled */
  468.  
  469.                 /* update the find prompt text */
  470.                 SetRect(&rectTemp,44,153,314,169);
  471.                 EraseRect(&rectTemp);
  472.                 TextFont(systemFont);
  473.                 TextSize(12);
  474.                 MoveTo(47,166);
  475.                 DrawString("\pFind what selection expression?");
  476.                 TextFont(sFontNum);
  477.                 TextSize(9);
  478.                 }  /* else if !sTemp */
  479.             }  /* if sHit */
  480.         else
  481.             {
  482.             GetDItem(pdlogFind,SELECTION_EXPRESSION_RADIO,&sDialogType,&hdlogItem,&rectTemp);                        /* get the item handle */
  483.             hctrlTemp = (ControlHandle) hdlogItem;                                                                    /* change dialog handle to control handle */
  484.             sTemp = GetCtlValue(hctrlTemp);                                                                            /*    get the current Checkbox value */
  485.             if (sTemp & 1)
  486.                 {
  487.                 /* enable SEARCH_BACKWARD_CHECK */
  488.                 GetDItem(pdlogFind,SEARCH_BACKWARD_CHECK,&sDialogType,&hdlogItem,&rectTemp);                        /* get the item handle */
  489.                 hctrlTemp = (ControlHandle) hdlogItem;                                                                /* change dialog handle to control handle */
  490.                 HiliteControl(hctrlTemp,0);                                                                            /* set to no highlighting */
  491.  
  492.                 /* update the find prompt text */
  493.                 SetRect(&rectTemp,44,153,314,169);
  494.                 EraseRect(&rectTemp);
  495.                 TextFont(systemFont);
  496.                 TextSize(12);
  497.                 MoveTo(47,166);
  498.                 DrawString("\pFind what string?");
  499.                 TextFont(sFontNum);
  500.                 TextSize(9);
  501.                 }  /* if sTemp */
  502.             }  /* else if sHit */
  503.         for (sIndex = LITERAL_RADIO; sIndex <= SELECTION_EXPRESSION_RADIO; sIndex++)
  504.             {
  505.             /* clear all radios */
  506.             GetDItem(pdlogFind,sIndex,&sDialogType,&hdlogItem,&rectTemp);                                            /* get the Radio handle */
  507.             hctrlTemp = (ControlHandle) hdlogItem;                                                                    /* get the control handle */
  508.             SetCtlValue(hctrlTemp,0);                                                                                /* turn the radio selection off */
  509.             }  /* for sIndex */
  510.         SetCtlValue(hctrlItem,1);                                                                                    /* turn the one radio selection on */
  511.         }  /* if sHit */
  512.     }  /* do */
  513. while (chDialogExit == false);
  514.  
  515. /* Get results after dialog */
  516. fGoOn = true;                                                                                                        /* initialize */
  517. GetKeys(kmapExit);
  518. if ((kmapExit[1] & 1) > 0)
  519.     {
  520.     /* a shift key was held down when exiting the dialog - temporarily reverse the search direction */
  521.     fReverse = true;
  522.     }  /* if kmapExit[] */
  523. else
  524.     {
  525.     fReverse = false;
  526.     }  /* else if kmapExit[] */
  527. switch (sHit)
  528.     {
  529.     case FIND_BUTTON :
  530.         {
  531.         /* do nothing */
  532.         break;
  533.         }  /* case REPLACE_BUTTON */
  534.     case CANCEL_BUTTON :
  535.         {
  536.         fGoOn = false;
  537.         break;
  538.         }  /* case CANCEL_BUTTON */
  539.     }  /* switch sHit */
  540.  
  541. if (fGoOn)
  542.     {
  543.     fBeep = true;                                                                                                    /* initialize */
  544.     GetDItem(pdlogFind,FIND_TEXT_EDIT,&sDialogType,&hdlogItem,&rectTemp);                                            /* get the item handle */
  545.     GetIText(hdlogItem,&strTemp);                                                                                     /* get the text entered */
  546.     if ((int) strTemp[0] > 0)
  547.         {
  548.         pfilFindCommand = fopen(getenv("findagainscript"),"w");
  549.         if (pfilFindCommand != NULL)
  550.             {
  551.             /* the command output files were successfully opened */
  552.             fBeep = false;                                                                                            /* disable error beep */
  553.             GetDItem(pdlogFind,CASE_SENSITIVE_CHECK,&sDialogType,&hdlogItem,&rectTemp);                                /* get the Checkbox handle */
  554.             hctrlItem = (ControlHandle) hdlogItem;                                                                    /* get the Checkbox handle */
  555.             (void) fprintf(pfilFindCommand,"Set CaseSensitive %d\n",GetCtlValue(hctrlItem));
  556.                 
  557.             GetDItem(pdlogFind,SEARCH_BACKWARD_CHECK,&sDialogType,&hdlogItem,&rectTemp);                            /* get the Checkbox handle */
  558.             hctrlItem = (ControlHandle) hdlogItem;                                                                    /* get the Checkbox handle */
  559.             fSearchBackward = (Boolean) GetCtlValue(hctrlItem);
  560.             (void) fprintf(pfilFindCommand,"Set SearchBackward %u\n",fSearchBackward);
  561.             
  562.             sIndex = LITERAL_RADIO;                                                                                    /* start at the first radio in this group */
  563.             do
  564.                 {
  565.                 GetDItem(pdlogFind,sIndex,&sDialogType,&hdlogItem,&rectTemp);                                        /* get the radio handle */
  566.                 hctrlItem = (ControlHandle) hdlogItem;                                                                /* get the radio handle */
  567.                 sTemp = GetCtlValue(hctrlItem);                                                                        /* get the radio value */
  568.                 sIndex++;
  569.                 }  /* do */
  570.             while ((sTemp != 1) && (sIndex <= SELECTION_EXPRESSION_RADIO));
  571.             sSearchType = sIndex - LITERAL_RADIO - 1;
  572.             (void) fprintf(pfilFindCommand,"Set SearchType %d\n",sSearchType);
  573.             
  574.             p2cstr(strTemp);
  575.             pszEnv = getenv("lastfindstring");                                                                        /* get a pointer to the LastFindString environment variable */
  576.             if (pszEnv != NULL)
  577.                 {
  578.                 pfilSetup = fopen(pszEnv,"w");                                                                        /* try to open the file for writing */
  579.                 if (pfilSetup != NULL)
  580.                     {
  581.                     (void) fprintf(pfilSetup,"%s\n",strTemp);
  582.                     (void) fclose(pfilSetup);
  583.                     }  /* if pfilSetup */
  584.                 }  /* if pszEnv */
  585.     
  586.             if (fReverse)
  587.                 {
  588.                 fSearchBackward = !fSearchBackward;
  589.                 }  /* if fReverse */
  590.                 
  591.             switch (sSearchType)
  592.                 {
  593.                 case 0 : /* literal */
  594.                     {
  595.                     QuoteString(achQuote,strTemp);                                                                    /* quote ' characters as necessary */
  596.                     if (fSearchBackward)
  597.                         {
  598.                         (void) fprintf(pfilFindCommand,"Find \\'%s'\\ \"{Active}\"\n",achQuote);
  599.                         }  /* if fSearchBackward */
  600.                     else
  601.                         {
  602.                         (void) fprintf(pfilFindCommand,"Find /'%s'/ \"{Active}\"\n",achQuote);
  603.                         }  /* else if fSearchBackward */
  604.                     (void) fprintf(pfilFindCommand,"If {Status} != 0\nBeep\nEnd\n");
  605.                     break;
  606.                     }  /* case 0 */
  607.                 case 1 : /* entire word */
  608.                     {
  609.                     QuoteString(achQuote,strTemp);                                                                    /* quote ' characters as necessary */
  610.                     if (fSearchBackward)
  611.                         {
  612.                         (void) fprintf(pfilFindCommand,"Mark -y § '_New_Find_' \"{Active}\"\n");
  613.                         (void) fprintf(pfilFindCommand,"Find §¡1 \"{Active}\"\nFind Δ\\[¬{WordSet}]'%s'[¬{WordSet}]\\!1:/'%s'/Δ \"{Active}\"\nIf ({Status} != 0)\nFind '_New_Find_' \"{Active}\"\nBeep\nEnd\n",achQuote,achQuote);
  614.                         (void) fprintf(pfilFindCommand,"Unmark '_New_Find_' \"{Active}\"\n");
  615.                         }  /* if fSearchBackward */
  616.                     else
  617.                         {
  618.                         (void) fprintf(pfilFindCommand,"Find Δ/[¬{WordSet}]'%s'[¬{WordSet}]/ \"{Active}\"\n",achQuote);
  619.                         (void) fprintf(pfilFindCommand,"If {Status} != 0\nBeep\nElse\nFind /'%s'/ \"{Active}\"\nEnd\n",achQuote);
  620.                         }  /* else if fSearchBackward */
  621.                     break;
  622.                     }  /* case 1 */
  623.                 case 2 : /* selection expression */
  624.                     {
  625.                     (void) fprintf(pfilFindCommand,"Find %s \"{Active}\"\n",strTemp);
  626.                     (void) fprintf(pfilFindCommand,"If {Status} != 0\nBeep\nEnd\n");
  627.                     break;
  628.                     }  /* case 2 */
  629.                 }  /* switch sSearchType */
  630.     
  631.             /* add the new find string to the saved find string file, but only if it is unique */
  632.             pszEnv = getenv("findstrings");                                                                            /* get a pointer to the FindStrings environment variable */
  633.             if (pszEnv != NULL)
  634.                 {
  635.                 pfilSetup = fopen(pszEnv,"r+");                                                                        /* try to open the file for reading */
  636.                 if (pfilSetup != NULL)
  637.                     {
  638.                     fMatch = false;                                                                                    /* initialize */
  639.                     while (!feof(pfilSetup) && !fMatch)
  640.                         {
  641.                         if (fgets(achTemp,256,pfilSetup) != NULL)
  642.                             {
  643.                             usLen = strlen(achTemp);
  644.                             if (usLen > 0)
  645.                                 {
  646.                                 if (*(achTemp + usLen - 1) == (char) '\n')
  647.                                     {
  648.                                     usLen--;
  649.                                     *(achTemp + usLen) = '\0';                                                        /* remove the line feed character */
  650.                                     }  /* if *achTemp */
  651.                                 fMatch = fMatch || (strcmp(achTemp,strTemp) == 0);
  652.                                 }  /* if usLen */
  653.                             }  /* if fgets() */
  654.                         }  /* while !feof() */
  655.                     if (!fMatch)
  656.                         {
  657.                         (void) fprintf(pfilSetup,"%s\n",strTemp);                                                    /* add the unique new string to the end of the file */
  658.                         }  /* if !fMatch */
  659.                     (void) fclose(pfilSetup);
  660.                     }  /* if pfilSetup */
  661.                 }  /* if pszEnv */
  662.             (void) fclose(pfilFindCommand);
  663.             }  /* if pfilFindCommand */
  664.         else
  665.             {
  666.             SysBeep(3);
  667.             }  /* else if pfilFindCommand */
  668.         }  /* if strTemp[] */
  669.     if (fBeep)
  670.         {
  671.         SysBeep(3);                                                                                                    /* signal error */
  672.         }  /* if fBeep */
  673.     }  /* if fGoOn */
  674. LDispose(hlistFind);
  675. DisposDialog(pdlogFind);                                                                                             /* flush the dialog out of memory */
  676. }  /* FindDialog() */
  677.  
  678. void main(void)
  679. {
  680. (void) signal(SIGINT,SIG_IGN);        /* disable command-. because aborting with the dialog up is a BAD THING */
  681. InitGraf(&qd.thePort);                /* initialize QuickDraw */
  682. SetFScaleDisable(true);
  683. FlushEvents(everyEvent,0);            /* start with no pending events to handle */
  684. InitCursor();                        /* start with a visible arrow cursor */
  685. (void) TEFromScrap();                /* Get any MPW text scrap */
  686. FindDialog();                        /* open the modal dialog */
  687. FlushEvents(everyEvent,0);            /* exit with no pending events to handle */
  688. exit(0);
  689. }  /* main() */
  690.  
  691. /* end of NewFindTool.c */